<template>
    <h2>reactive的使用</h2>
    <h3>名字：{{user.name}}</h3>
    <h3>年龄：{{user.age}}</h3>
    <h3>性别:{{user.gender}}</h3>
    <h3>相关：{{user.wife}}</h3>
    <hr>
    <button @click="updateUser">更新数据</button>

</template>

<script lang="ts">
import { defineComponent, reactive,  } from 'vue';
export default defineComponent({
  name: 'App',

  // 需求：显示用户的相关信息，点击按钮，可以更新用户的相关信息数据
  /*
  作用：定义多个数据的响应式
  const proxt = reactive(obj) :接收一个普通对象然后返回该普通对象的响应式代理器对象
  响应式转换是“深层的”：会影响对象内部所有嵌套的属性
  内部基于ES6 的Proxy实现，通过代理对象操作源对象内部数据都是响应式的
  */

  setup(){
    // 把数据变成响应式数据
    // const obj: any = {   //为了在使用obj.gender="男" 的时候不出现这种错误的提示信息才这么书写
    const obj: any = {
      name: "小浩",
      age: 18,
      wife:{
        name: "敏怡",
        age: 18,
        cars:['奔驰','红旗',"比亚迪"]
      },
    }
    // 把数据变成响应式的数据
    // 返回的是一个Proxy的代理对象，被代理的目标对象就是obj对象
    // user现在是代理对象，obj是目标对象
    // user对象的类型是Proxy
    const user = reactive<any>(obj)
    console.log(user)

    // 方法
    // function updateUser(){
    //   console.log("123456")
    // }
  
    function updateUser(){
      // 直接使用目标对象的方式来更新目标对象中的成员的值，是不可能的，只能使用代理对象的方式来更新数据（响应式数据）
      // obj.name += "===="
      // 下面的可以
      console.log("点击事件updateUser")
      user.name += "=="
      user.age += 2
      user.wife.name += "++"
      user.wife.cars[0] = "玛莎拉蒂"

      // user----》代理对象，obj------》目标对像
      // user对象或者obj对象添加一个新的属性，哪一种方式会影响界面的更新
      // obj.gender = "男" //这种方式，界面没有更新渲染
      // user.gender = '男'  //这种方式，界面可以更新想让，而且这个数据最终也添加到了obj对象上

      // user对象或者obj对象中移除一个已经存在的属性，哪一种方式会影响界面的更新
      // delete obj.age    //界面没有更新渲染2，obj中确实没有age这个属性
      // delete user.age     //  界面更新渲染了，obj中确实没有了age这个属性

      // 如果操作代理对象，目标对象的数据也会随之变化，同时如果想要在操作数据的时候，界面也要更新渲染，那么也操作代理对象
    }

    return{
      user,
      updateUser,
    }
  }

 
});
</script>
